package virtualstock.request;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.ejb.EJBException;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import virtualstock.entity.Game;
import virtualstock.entity.Player;
import virtualstock.exception.InvalidParameterException;
import virtualstock.exception.PlayerNotFoundException;
import virtualstock.util.PlayerDetails;

/**
 * Session Bean implementation class PlayerControllerBean
 */
@Stateful
public class PlayerControllerBean implements PlayerController {
	@PersistenceContext
	private EntityManager em;
	private Long playerID = null;

    /**
     * Default constructor. 
     */
    public PlayerControllerBean() {
        // TODO Auto-generated constructor stub
    }

	@Override
	public Long createPlayer(PlayerDetails details) 
		throws InvalidParameterException {
		// makes a new player and enters it into db
		Player player = null;
		
		if (details.getLastName() == null) {
			//System.out.println("InvalidParameterException: null lastName");
			throw new InvalidParameterException("null lastName");
		}
		
		if (details.getFirstName() == null) {
			//System.out.println("InvalidParameterException: null firstName");
			throw new InvalidParameterException("null firstName");
		}
		
		try {
			player = new Player(
					details.getEmail(),
					details.getPassword(),
					details.getFirstName(),
					details.getLastName());
			em.persist(player);
		} catch (Exception ex) {
			throw new EJBException("createPlayer: " + ex.getMessage());
		}
		
		return player.getPlayerID();
	}

	@Override
	public PlayerDetails getPlayerDetails(Long playerID) 
		throws InvalidParameterException, PlayerNotFoundException {
		// returns the PlayerDetails for the specified player
		PlayerDetails result = null;
		
		if (playerID == null) {
			System.out.println("InvalidParameterException: null playerID");
			throw new InvalidParameterException("null playerID");
		}
		
		try {
			Player player = em.find(Player.class, playerID);
			
			if (player == null) {
				System.out.println("PlayerNotFoundException");
				throw new PlayerNotFoundException(playerID);
			}
			else {
				result = new PlayerDetails(
						player.getPlayerID(),
						player.getEmail(),
						player.getPassword(),
						player.getFirstName(),
						player.getLastName());
			}
		} catch (Exception ex) {
			System.err.println("PlayerControllerBean.getPlayerDetails: Caught an exception.");
			ex.printStackTrace();
		}
		
		return result;
	}

	@Override
	public List<PlayerDetails> getPlayersOfGame(Long gameID) throws InvalidParameterException {
		// returns an ArrayList of PlayerDetails that correspond to the playerID specified
		// currently doesn't work
		Collection<Player> players = null;
		
		if (gameID == null) {
			throw new InvalidParameterException("null gameID");
		}
		
		try {
			Game game = em.find(Game.class, gameID);
			players = game.getPlayers();
		} catch (Exception ex) {
			throw new EJBException(ex.getMessage());
		}
		
		return copyPlayersToDetails(players);
	}
	
	@Override
	public List<PlayerDetails> getPlayersByEmail(String email) throws InvalidParameterException{
		//assuming the email address is unique
		Collection<Player> players = null;
		
		if(email == null) {
			throw new InvalidParameterException("null email address");
		}
		
		try{
			players = (List<Player>) em.createNamedQuery("Player.FindByEmail").setParameter("email", email).getResultList();
		} catch (Exception ex) {
			throw new EJBException(ex.getMessage());
		}
		
		if(players.isEmpty()){
			return null;
		}
		else {
			return copyPlayersToDetails(players);
		}
	}
	
	@Override
	public List<PlayerDetails> getAllPlayer(){
        Collection<Player> players = null;
        try {
        	players = (List<Player>) em.createNamedQuery("Player.FindAllPlayer").getResultList();
        } catch (Exception ex) {
        	throw new EJBException(ex.getMessage());
        }
        
        if(players.isEmpty()) {
        	return null;
        } else {
        	return this.copyPlayersToDetails(players);
        }
}


	@Override
	public void removePlayer(Long playerID) 
		throws InvalidParameterException, PlayerNotFoundException {
		// removes player from db
		if (playerID == null) {
			System.out.println("InvalidParameterException: null playerID");
			throw new InvalidParameterException("null playerID");
		}
		
		try {
			Player player = em.find(Player.class, playerID);
			
			if (player == null) {
				System.out.println("PlayerNotFoundException");
				throw new PlayerNotFoundException();
			}
			else {
				em.remove(player);
			}
		} catch (Exception ex) {
			throw new EJBException("removePlayer: " + ex.getMessage());
		}
		
	}
	
    private List<PlayerDetails> copyPlayersToDetails(Collection<Player> players) {
        List<PlayerDetails> detailsList = new ArrayList<PlayerDetails>();
        Iterator<Player> i = players.iterator();

        try {
            while (i.hasNext()) {
            	Player player = (Player) i.next();
                PlayerDetails details = new PlayerDetails(
                		player.getPlayerID(),
                		player.getEmail(),
                		player.getPassword(),
                		player.getFirstName(),
                		player.getLastName());
                detailsList.add(details);
            }
        } catch (Exception ex) {
            throw new EJBException(ex.getMessage());
        }

        return detailsList;
    }


}
